// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2004-6-11

#ifndef __THREAD_H_COMMON_BASE__
#define __THREAD_H_COMMON_BASE__

#pragma once

//##ModelId=44C4B5CF0213
class CJoyCriticalSection
{
protected:
	//##ModelId=44C4B5CF0214
    volatile CRITICAL_SECTION m_cs;
public:
	//##ModelId=44C4B5CF0222
    CJoyCriticalSection();
	//##ModelId=44C4B5CF0223
    ~CJoyCriticalSection();
	//##ModelId=44C4B5CF0224
    void Lock();
	//##ModelId=44C4B5CF0225
    void Unlock();
	//##ModelId=44C4B5CF0226
    bool TryLock();
};

//##ModelId=44C4B5CF0232
class CJoyAutoCS
{
protected:
	//##ModelId=44C4B5CF0234
    CJoyCriticalSection&  m_cs;

	//##ModelId=44C4B5CF0242
    void operator = (const CJoyAutoCS& a);
public:
	//##ModelId=44C4B5CF0262
    CJoyAutoCS(CJoyCriticalSection& cs):
        m_cs(cs)
    {
        m_cs.Lock();
    }
	//##ModelId=44C4B5CF0264
    ~CJoyAutoCS()
    {
        m_cs.Unlock();
    }
};

extern "C" long __cdecl _InterlockedIncrement(long volatile *);
extern "C" long __cdecl _InterlockedDecrement(long volatile *);

#pragma intrinsic(_InterlockedIncrement)
#pragma intrinsic(_InterlockedDecrement)

//##ModelId=44C4B5CF0271
class CJoyAtomCount
{
protected:
	//##ModelId=44C4B5CF0272
    long volatile m_nValue;
public:
	//##ModelId=44C4B5CF0273
    CJoyAtomCount(long v = 0):
        m_nValue(v)
    {
    }
	//##ModelId=44C4B5CF0275
    long operator++()
    {
        return ::_InterlockedIncrement(&m_nValue);
    }
	//##ModelId=44C4B5CF0280
    long operator--()
    {
        return ::_InterlockedDecrement(&m_nValue);
    }
	//##ModelId=44C4B5CF0281
    long operator ++ (int)
    {
        return ::_InterlockedIncrement(&m_nValue)-1;
    }
	//##ModelId=44C4B5CF0283
    long operator -- (int)
    {
        return ::_InterlockedDecrement(&m_nValue)+1;
    }
	//##ModelId=44C4B5CF0285
    operator long() const
    {
        return m_nValue;
    }
	//##ModelId=44C4B5CF0287
    long operator = (long v)
    {
        m_nValue = v;
        return v;
    }
};

#endif  // __THREAD_H_COMMON_BASE__
